package com.kingsoft.dc.khaos.module.spark.udf

import java.io.UnsupportedEncodingException
import java.lang
import java.security.{InvalidKeyException, MessageDigest, NoSuchAlgorithmException}
import java.sql.Timestamp
import java.time._
import java.time.format.{DateTimeFormatter, DateTimeParseException}

import javax.crypto.spec.SecretKeySpec
import javax.crypto.{BadPaddingException, Cipher, IllegalBlockSizeException, NoSuchPaddingException}
import org.apache.commons.codec.binary.Base64
import org.apache.spark.internal.Logging

//import scala.runtime.RichFloat

/**
  * Created by  on 19/3/14.
  */
object ColumnHandler extends Logging{
  /**
    * 空值处理udf
    */
  def null2Date(input: Any): Timestamp = {
    if (input.toString == null) {
      new Timestamp(0)
    }else{
      input.asInstanceOf[Timestamp]
    }
  }
  def null2Float(input: Any): java.lang.Float = {
    if (input.toString == null) {
      new lang.Float(0)
    }else{
      input.asInstanceOf[java.lang.Float]
    }
  }
  def null2Int(input: Any): Integer = {
    if (input.toString == null) {
      new Integer(0)
    }else{
      input.asInstanceOf[Integer]
    }
  }

  val AES_KEY: String = "1234567890123456" //AES密钥,需要16位

  /**
    * MD5加密
    *
    * @param input 输入字符串
    * @return java.lang.String 加密后的字符串
    */
  def MD5(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"MD5加密: 需要加密的字符串不规范,input为[$input]")
    var md5: MessageDigest = null
    val algorithm:String="MD5"
    try {
      md5 = MessageDigest.getInstance(algorithm)
    }
    catch {
      case e: NoSuchAlgorithmException => {
        throw new NoSuchAlgorithmException(s"MD5加密: 指定算法不支持,algorithm为[$algorithm]")
      }
      case e: Exception=>{
        throw new Exception(s"MD5加密: "+e.getMessage)
      }
    }
    val byteArray: Array[Byte] = input.getBytes
    val md5Bytes: Array[Byte] = md5.digest(byteArray)
    var hexValue: String = ""
    var i: Integer = 0
    for (i <- 0 to md5Bytes.length - 1) {
      val str: Int = (md5Bytes(i).toInt) & 0xff
      if (str < 16) {
        hexValue = hexValue + "0"
      }
      hexValue = hexValue + (Integer.toHexString(str))
    }
    hexValue.toString
  }


  /**
    * Base64加密
    *
    * @param input 输入参数可以为中文字符
    * @return java.lang.String 返回Base64加密后的结果
    */
  def base64Encrypt(input: String): String = {

    if (input == null)
      throw new IllegalArgumentException(s"base64加密: 需要加密的字符串不规范,input为[$input]")
    if ("".equals(input))
      return ""
    var encryptString: String = ""

    val byteArray: Array[Byte] = input.getBytes //获取输入字符串字节数组
    encryptString = new Base64().encodeToString(byteArray) //base64转码生成加密字符串

    encryptString.toString //返回加密后的字符串
  }

  /**
    * Base64解密
    *
    * @param input 输入参数可以为中文字符
    * @return java.lang.String 返回Base64解密后的结果
    */
  def base64Decrypt(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"base64解密: 需要解密的字符串不规范,input为[$input]")
    if ("".equals(input))
      return ""
    var originalString: String = ""

    val byteArray: Array[Byte] = input.getBytes //获取输入字符串字节数组
    val decodeArray: Array[Byte] = new Base64().decode(byteArray) //base64解码生成原始字符串
    originalString = new String(decodeArray)

    originalString.toString //返回原始字符串
  }

  /**
    * AES加密
    *
    * @param input 输入参数可以为中文字符
    * @return java.lang.String 返回加密后的加密字段
    */
  def aesEncrypt(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"aes加密: 需要加密的字符串不规范,input为[$input]")
    var encryptString: String = ""
    try {
      val raw: Array[Byte] = AES_KEY.getBytes
      val aesKeySpec: SecretKeySpec = new SecretKeySpec(raw, "AES")
      val cipher: Cipher = Cipher.getInstance("AES/ECB/PKCS5Padding") // "算法/模式/补码方式"
      cipher.init(Cipher.ENCRYPT_MODE, aesKeySpec) //初始化密钥
      val encrypted: Array[Byte] = cipher.doFinal(input.getBytes) //加密得到字节数组
      encryptString = new Base64().encodeToString(encrypted) // 使用BASE64做转码功能
    }
    catch {
      case e: NoSuchAlgorithmException => {
        throw new NoSuchAlgorithmException("aes加密: 指定算法不支持")
      }
      case e: NoSuchPaddingException => {
        throw new NoSuchPaddingException("aes加密: 指定填充方式Padding不支持")
      }
      case e: InvalidKeyException => {
        throw new InvalidKeyException("aes加密: 指定密钥无效")
      }
      case e: IllegalBlockSizeException => {
        throw new IllegalBlockSizeException(s"aes加密: 输入字符串生成的字节数组长度异常,input为[$input]")
      }
      case e: BadPaddingException => {
        throw new BadPaddingException("aes加密: 算法Padding填充失败")
      }
      case e: Exception=>{
        throw new Exception(s"aes加密: "+e.getMessage)
      }
    }
    encryptString.toString //返回解密后的字符串
  }

  /**
    * AES解密
    *
    * @param input 输入参数可以为中文字符
    * @return java.lang.String 返回解密后的原始字段
    */
  def aesDecrypt(input: String): String = {

    if (input == null)
      throw new IllegalArgumentException(s"aes解密: 需要解密的字符串不规范,input为[$input]")
    if (input == "")
      return ""
    var originalString: String = ""
    try {
      val raw: Array[Byte] = AES_KEY.getBytes
      val aesKeySpec: SecretKeySpec = new SecretKeySpec(raw, "AES")
      val cipher: Cipher = Cipher.getInstance("AES/ECB/PKCS5Padding") // "算法/模式/补码方式"
      cipher.init(Cipher.DECRYPT_MODE, aesKeySpec) //初始化密钥
      val encrypted1: Array[Byte] = new Base64().decode(input) //首先对输入字符串进行base64解码
      val original: Array[Byte] = cipher.doFinal(encrypted1) //对解码后的字节数组进行aes解密
      originalString = new String(original)
    }
    catch {
      case e: NoSuchAlgorithmException => {
        throw new NoSuchAlgorithmException("aes解密: 指定算法不支持")
      }
      case e: NoSuchPaddingException => {
        throw new NoSuchPaddingException("aes解密: 指定填充方式Padding不支持")
      }
      case e: InvalidKeyException => {
        throw new InvalidKeyException("aes解密: 指定密钥无效")
      }
      case e: IllegalBlockSizeException => {
        throw new IllegalBlockSizeException(s"aes解密: 输入字符串生成的字节数组长度异常,input为[$input]")
      }
      case e: BadPaddingException => {
        throw new BadPaddingException("aes解密: 算法Padding填充失败")
      }
      case e: Exception=>{
        throw new Exception(s"aes解密: "+e.getMessage)
      }
    }
    originalString.toString //返回解密后的原始字符串
  }

  /**
    * 全脱敏
    *
    * @param input 输入参数可以为中文字符
    * @return java.lang.String 返回数据全脱敏后的结果，不可逆。传入数据，返回结果为“****”
    */
  def dataHide(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"数据全脱敏: 需要脱敏的字符串不规范,input为[$input]")
    if ("".equals(input))
      return ""
    var hideString: String = ""

    hideString = Array.fill(input.length)('*').mkString //生成和输入字符串等长的*

    hideString.toString //返回数据全脱敏后的结果
  }

  /**
    * 部分脱敏
    *
    * @param input 输入参数可以为中文字符
    * @return java.lang.String 返回数据部分脱敏后的结果，不可逆。传入数据，返回结果形如“138****4567”
    */
  def halfDataHide(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"数据部分脱敏: 需要脱敏的字符串不规范,input为[$input]")
    if ("".equals(input))
      return ""
    var halfHideString: String = ""

    //长度小于3的字符串直接处理
    if (input.length < 3) {
      input.length match {
        case 1 => halfHideString = input //input:张 halfHideString:张
        case 2 => halfHideString = input.charAt(0) + "*" //input:张三 halfHideString:张*
      }
    } else {
      val buffer: StringBuffer = new StringBuffer()
      //长度大于等于3的字符串对3取模 进行匹配
      (input.length % 3) match {
        case 0 => { //input: 123456789 halfHideString:123***789
          halfHideString = buffer.append(input.substring(0, input.length / 3))
              .append(Array.fill(input.length / 3)('*').mkString)
              .append(input.substring(input.length - input.length / 3, input.length))
              .toString
        }
        case _ => { //input: 13800006400 halfHideString:138****6400
          halfHideString = buffer.append(input.substring(0, input.length / 3))
              .append(Array.fill((input.length / 3) + 1)('*').mkString)
              .append(input.substring(input.length - (input.length / 3) - 1, input.length))
              .toString
        }
      }
    }

    halfHideString.toString //返回数据部分脱敏后的结果
  }


  /**
    * 判断是否为空
    *
    * @param input 输入参数
    * @return boolean  如果input为null、""、" "三种情况就返回true，否则返回false
    */
  def isNull(input: Any): Boolean = {
    if (input == null || "".equals(input.toString) || "".equals(input.toString.trim))
      return true
    false
  }

  /**
    * 判断是否不为空
    *
    * @param input 输入参数
    * @return boolean 如果a为非null、非""、非" "三种情况就返回true，否则返回false
    */
  def isNotNull(input: Any): Boolean = {
    if (input == null || "".equals(input.toString) || "".equals(input.toString.trim))
      return false
    true
  }

  /**
    * 返回str中首个ASCII字符串的整数值
    *
    * @param input 输入str
    * @return int str中首个ASCII字符串的整数值
    */
  def ascii(input: String): Int = {
    if (input == null || "".equals(input))
      throw new IllegalArgumentException(s"获得首个字符的ascii: 输入的字符串不规范,input为[$input]")
    var firstChar: Int = 0

    firstChar = input.charAt(0)

    firstChar
  }

  /**
    * 连接字符串
    *
    * @param input1 需要连接的第一个字符串
    * @param input2 需要连接的第二个字符串
    * @return java.lang.String 拼接后的字符串
    */
  def concat(input1: String, input2: String): String = {
    if (input1 == null && input2 == null) //如果参数都为null,则抛出异常
      throw new IllegalArgumentException(s"字符串连接: 需要连接的两个字符串不规范,input1,input2为[$input1],[$input2]")
    if (input1 == null) //如果第一个字符串为null,直接返回第二个字符串
      return input2
    if (input2 == null) //如果二个字符串为null,直接返回第一个字符串
      return input1
    input1 + input2
  }

  /**
    * 指定分隔符连接字符串
    *
    * @param input1    需要连接的第一个字符串
    * @param input2    需要连接的第二个字符串
    * @param separator 指定分隔符
    * @return java.lang.String 拼接后的字符串
    */
  def concat(input1: String, input2: String, separator: String): String = {
    if (input1 == null && input2 == null) //如果参数都为null,则抛出异常
      throw new IllegalArgumentException(s"指定分隔符连接字符串: 需要连接的两个字符串不规范,input1,input2为[$input1],[$input2]")
    if (separator == null) //如果分割符为null,则抛出异常
      throw new IllegalArgumentException(s"指定分隔符连接字符串: 指定的分隔符不规范,separator为[$separator]")
    if (input1 == null) //如果第一个字符串为null,直接返回第二个字符串
      return input2
    if (input2 == null) //如果二个字符串为null,直接返回第一个字符串
      return input1
    input1 + separator + input2
  }

  /**
    * 返回字符串长度
    *
    * @param input 输入的字符串
    * @return int 字符串长度
    */
  def length(input: String): Int = {
    if (input == null)
      throw new IllegalArgumentException(s"返回字符串长度: 输入的字符串不规范,input为[$input]")
    input.length
  }

  /**
    * 去掉字符串中的所有空格
    *
    * @param input 输入字符串
    * @return java.lang.String
    */
  def trimAll(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"去掉字符串中的所有空格: 输入的字符串不规范,input为[$input]")
    input.replaceAll(" ", "")
  }

  /**
    * 去掉字符串前后空格
    *
    * @param input 输入字符串
    * @return java.lang.String
    */
  def trim(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"去掉字符串前后空格: 输入的字符串不规范,input为[$input]")
    input.trim
  }

  /**
    * 翻转字符串
    *
    * @param input 输入字符串
    * @return java.lang.String
    */
  def reverse(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"翻转字符串: 输入的字符串不规范,input为[$input]")
    input.reverse.toString
  }

  /**
    * 返回指定个数空格生成的字符串
    *
    * @param input 空格个数
    * @return java.lang.String
    */
  def space(input: Int): String = {
    if (input < 0)
      throw new IllegalArgumentException(s"返回指定个数空格生成的字符串: 指定个数input小于0,input为[$input]")
    var spaceString: String = ""

    spaceString = Array.fill(input)(" ").mkString //使用集合填充个数 n*input(空格数)


    spaceString.toString
  }

  /**
    * 返回字符串从第一个字符开始到第n个字符
    *
    * @param input  输入字符串
    * @param length 需要截取的长度
    * @return java.lang.String
    */
  def subStr(input: String, length: Int): String = {
    if (input == null)
      throw new IllegalArgumentException(s"返回字符串从第一个字符开始到第n个字符: 输入的字符串不规范,input为[$input]")
    if (length < 0)
      throw new IllegalArgumentException(s"返回字符串从第一个字符开始到第n个字符: 需要截取的长度length小于0,length为[$length]")
    if ("".equals(input))
      return ""

    var subString: String = ""

    if (length < input.length) {
      subString = input.substring(0, length)
    } else { //如果输入长度大于字符串原本长度,则返回整个字符串
      subString = input
    }

    subString.toString
  }

  /**
    * 返回第1个指定位置字符之后的所有字符
    *
    * @param input 输入字符串
    * @param tag   指定字符
    * @return java.lang.String 返回字符串“inputCol”中“tag”之后的所有字符，不包含指定字符“tag”
    */
  def subStrLater(input: String, tag: String): String = {
    if (input == null || "".equals(input))
      throw new IllegalArgumentException(s"返回第1个指定位置字符之后的所有字符: 输入的字符串不规范,input为[$input]")
    if (tag == null || "".equals(tag))
      throw new IllegalArgumentException(s"返回第1个指定位置字符之后的所有字符: 指定字符串不规范,tag为[$tag]")

    var laterString: String = ""

    val index: Int = input.indexOf(tag)
    if (index < 0) //如果input包含tag,则返回对应字符串,不包含tag,返回空字符串
      throw new IllegalArgumentException(s"返回第1个指定位置字符之后的所有字符: 指定字符串不规范,tag[$tag]不存在")
    laterString = input.substring(index + tag.length)

    laterString.toString
  }

  /**
    * 返回第1个指定位置字符之前的所有字符
    *
    * @param input 输入字符串
    * @param tag   指定字符
    * @return java.lang.String 返回字符串“inputCol”中“tag”之前的所有字符，不包含指定字符“tag”
    */
  def subStrBefore(input: String, tag: String): String = {
    if (input == null || "".equals(input))
      throw new IllegalArgumentException(s"返回第1个指定位置字符之前的所有字符: 输入的字符串不规范,为[$input]")
    if (tag == null || "".equals(tag))
      throw new IllegalArgumentException(s"返回第1个指定位置字符之前的所有字符: 指定字符串不规范,tag为[$tag]")

    var beforeString: String = ""

    val index: Int = input.indexOf(tag)
    if (index < 0) //如果input包含tag,则返回对应字符串,不包含tag,返回空字符串
      throw new IllegalArgumentException(s"返回第1个指定位置字符之前的所有字符: 指定字符串不规范,tag[$tag]不存在")
    beforeString = input.substring(0, index)

    beforeString.toString
  }

  /**
    * 返回指定两个字符中间的所有字符
    *
    * @param input 输入字符串
    * @param bef   指定的第一个字符
    * @param end   指定的第二个字符
    * @return java.lang.String 返回字符“bef”到“end”之间的所有字符，不含“bef”和“end”, 如果包含多个,则取第一个bef和最后一个end
    */
  def subStrMid(input: String, bef: String, end: String): String = {
    if (input == null || "".equals(input))
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 输入的字符串不规范,input为[$input]")
    if (bef == null || "".equals(bef))
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 指定字符串不规范,bef为[$bef]")
    if (end == null || "".equals(end))
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 指定字符串不规范,end为[$end]")

    var midString: String = ""

    val indexBef: Int = input.indexOf(bef)
    val indexEnd: Int = input.lastIndexOf(end) //input中包含最后一个end的索引值

    if (indexBef < 0)
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 指定的第一个字符bef[$bef]不存在")
    if (indexEnd < 0)
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 指定的第二个字符end[$end]不存在")
    if (indexBef > indexEnd)
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 指定两个字符中间不存在任何字符")
    if (indexBef == indexEnd)
      return ""
    if(indexBef + bef.length <= indexEnd){
      midString = input.substring(indexBef + bef.length, indexEnd)
    }else{
      throw new IllegalArgumentException(s"返回指定两个字符中间的所有字符: 指定两个字符中间不存在任何字符")
    }
    midString.toString
  }

  /**
    * 将输入字符串转换为大写字符
    *
    * @param input 输入字符串
    * @return java.lang.String 转换大写后的字符串
    */
  def toUpper(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"将输入字符串转换为大写字符串: 输入的字符串不规范,input为[$input]")
    if ("".equals(input))
      return ""
    input.toUpperCase
  }

  /**
    * 将输入字符串转换为小写字符
    *
    * @param input 输入字符串
    * @return java.lang.String 转换小写后的字符串
    */
  def toLower(input: String): String = {
    if (input == null)
      throw new IllegalArgumentException(s"将输入字符串转换为小写字符串: 输入的字符串不规范,input为[$input]")
    if ("".equals(input))
      return ""
    input.toLowerCase
  }


  /**
    * 日期格式化函数
    *
    * @param timestamp 时间秒值 单位:秒
    * @param format    转化的格式  eg: yyyy-MM-dd hh:mm:ss
    * @return java.lang.String 转化后的时间
    */
  def fromUnixTime(timestamp: Long, format: String): String = {
    if (format == null || "".equals(format) || "".equals(format.trim))
      throw new IllegalArgumentException(s"日期格式化: 指定日期格式不规范,format为[$format]")
    var formatTime: String = ""
    var second: Instant = null
    var localDateTime: LocalDateTime = null
    try {
      second = Instant.ofEpochSecond(timestamp) //获得时间戳
      localDateTime = LocalDateTime.ofInstant(second, ZoneId.systemDefault()) //设置时间
      formatTime = localDateTime.format(DateTimeFormatter.ofPattern(format.trim)) //对时间进行格式化
    } catch {
      case e: DateTimeException => {
        throw new DateTimeException(s"日期格式化: 传入的时间秒值超过阈值或无效,timestamp为[$timestamp]," +
            s"最小秒值 = -31557014167219200L, 最大秒值 = 31556889864403199L")
      }
      case e: IllegalArgumentException => {
        throw new IllegalArgumentException(s"日期格式化: 指定格式不规范,format为[$format]")
      }
      case e: Exception=>{
        throw new Exception(s"日期格式化: "+e.getMessage)
      }
    }
    formatTime.toString
  }

  /**
    * 获取当前UTC时间
    *
    * @return java.lang.String 返回时间秒值
    */
  def currentTimestamp(): Long = {
    var currentTimestamp: Long = 0

    currentTimestamp = System.currentTimeMillis() / 1000 //毫秒值转换为秒值

    currentTimestamp
  }

  /**
    * 固定格式时间转UTC时间 格式: yyyy-MM-dd HH:mm:ss
    *
    * @param date 传入的时间
    * @return long UTC时间
    */
  def unixTimestamp(date: String): Long = {
    if (date == null || "".equals(date) || "".equals(date.trim))
      throw new IllegalArgumentException(s"固定格式时间转UTC时间: 输入的日期字符串不规范,date为[$date]")
    var unixTimestamp: Long = 0
    val pattern: String = "yyyy-MM-dd HH:mm:ss"
    try {
      val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern(pattern) //设置日期格式
      val localDateTime: LocalDateTime = LocalDateTime.parse(date.trim, formatter) //对输入日期进行转换
      unixTimestamp = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli / 1000 //毫秒值转化为秒值
    } catch {
      case e: IllegalArgumentException => {
        throw new IllegalArgumentException(s"固定格式时间转UTC时间: 指定格式不规范,pattern为[$pattern]")
      }
      case e: DateTimeParseException => {
        throw new DateTimeParseException(s"固定格式时间转UTC时间: 传入的日期不规范,转换失败,date为[$date],pattern为[$pattern]", e.getParsedString, e.getErrorIndex)
      }
      case e: Exception => {
        throw new Exception(s"固定格式时间转UTC时间: "+e.getMessage)
      }
    }
    unixTimestamp
  }

  /**
    * 指定格式时间转UTC时间
    *
    * @param date    传入的时间
    * @param pattern 指定格式
    * @return long UTC时间
    */
  def unixTimestamp(date: String, pattern: String): Long = {
    if (date == null || "".equals(date) || "".equals(date.trim))
      throw new IllegalArgumentException(s"指定格式时间转UTC时间: 输入的日期字符串不规范,date为[$date]")
    if (pattern == null || "".equals(pattern) || "".equals(pattern.trim))
      throw new IllegalArgumentException(s"指定格式时间转UTC时间: 指定的格式不规范,pattern为[$pattern]")

    var parseDate = date.trim

    /*if (pattern.trim.length <= parseDate.length)
        parseDate = parseDate.substring(0, pattern.trim.length)*/

    var unixTimestamp: Long = 0
    var formatter: DateTimeFormatter = null
    try {
      formatter = DateTimeFormatter.ofPattern(pattern.trim) //设置日期格式
      val parse: LocalDateTime = LocalDateTime.parse(parseDate, formatter) //对输入日期进行转换
      unixTimestamp = Timestamp.valueOf(parse).getTime
      unixTimestamp = unixTimestamp / 1000 //毫秒值转化为秒值
    } catch {
      case e: IllegalArgumentException => {
        throw new IllegalArgumentException(s"指定格式时间转UTC时间: 指定格式不规范,pattern为[$pattern]")
      }
      case e: DateTimeParseException => {
        //如果发生了转换异常,可能是输入的pattern只包含日期格式,不包含时间(HH:mm:ss)格式
        //LocalDateTime不支持,所以抛出转换异常,此时使用LocalDate进行转换
        try {
          val parse: LocalDate = LocalDate.parse(parseDate, formatter)
          unixTimestamp = Timestamp.valueOf(parse.atStartOfDay()).getTime
          unixTimestamp = unixTimestamp / 1000
        } catch {
          case e: DateTimeParseException => {
            throw new DateTimeParseException(s"指定格式时间转UTC时间: 传入的日期不规范,转换失败,date为[$date],pattern为[$pattern]", e.getParsedString, e.getErrorIndex)
          }
          case e: Exception => {
            throw new Exception(s"指定格式时间转UTC时间: "+e.getMessage)
          }
        }
      }
      case e: Exception => {
        throw new Exception(s"指定格式时间转UTC时间: "+e.getMessage)
      }
    }
    unixTimestamp
  }

  /**
    * 返回日期字符串的日期部分
    *
    * @param timestamp 指定日期
    * @return java.lang.String 日期部分 eg : to_date("1970-01-01 00:00:00") = "1970-01-01"
    */
  def toDate(timestamp: String): String = {
    if (timestamp == null || "".equals(timestamp) || "".equals(timestamp.trim))
      throw new IllegalArgumentException(s"返回日期字符串的日期部分 输入的日期字符串不规范,timestamp为[$timestamp]")
    var formatDate: String = ""
    val pattern: String = "yyyy-MM-dd"
    try {
      var formatter: DateTimeFormatter = getFormatter(timestamp.trim) //调用getFormatter方法,获得与输入日期字符串相对应的formatter
      val parseDate: LocalDate = LocalDate.parse(timestamp.trim, formatter) //对日期字符串进行转换
      formatter = DateTimeFormatter.ofPattern(pattern)
      formatDate = parseDate.format(formatter)
    } catch {
      case e: DateTimeParseException => {
        throw new DateTimeParseException(s"返回日期字符串的日期部分: 指定日期不规范,转换失败,timestamp为[$timestamp],pattern为[$pattern]", e.getParsedString, e.getErrorIndex)
      }
      case e: IllegalArgumentException => {
        throw new IllegalArgumentException(s"返回日期字符串的日期部分: 指定格式不规范,pattern为[$pattern]")
      }
      case e: DateTimeException => {
        throw new DateTimeException(s"返回日期字符串的日期部分: "+e.getMessage)
      }
      case e: Exception => {
        throw new Exception(s"返回日期字符串的日期部分: "+e.getMessage)
      }
    }
    formatDate
  }

  /**
    * 返回时间字符串的年份
    *
    * @param date 时间字符串
    * @return int eg : year("1970-01-01 00:00:00") = 1970, year("1970-01-01") = 1970
    */
  def year(date: String): Int = {
    if (date == null || "".equals(date) || "".equals(date.trim))
      throw new IllegalArgumentException(s"返回时间字符串的年份: 输入的日期字符串不规范,date为[$date]")
    var dateYear: Int = 0
    try {
      val formatter: DateTimeFormatter = getFormatter(date.trim) //调用getFormatter方法,获得与输入日期字符串相对应的formatter
      val parseDate: LocalDate = LocalDate.parse(date.trim, formatter)
      dateYear = parseDate.getYear
    }
    catch {
      case e: DateTimeParseException => {
        throw new DateTimeParseException(s"返回日期字符串的日期部分: 指定日期不规范,转换失败,date为[$date]", e.getParsedString, e.getErrorIndex)
      }
      case e: Exception => {
        throw new Exception(s"返回日期字符串的日期部分: "+e.getMessage)
      }
    }
    dateYear
  }


  /**
    * 返回时间字符串的季度
    *
    * @param date 时间字符串
    * @return int eg : quarter('2015-04-08') = 2
    */
  def quarter(date: String): Int = {
    if (date == null || "".equals(date) || "".equals(date.trim))
      throw new IllegalArgumentException(s"返回时间字符串的季度: 输入的日期字符串不规范,date为[$date]")
    var dateQuarter: Int = 0
    try {
      val formatter: DateTimeFormatter = getFormatter(date.trim) //调用getFormatter方法,获得与输入日期字符串相对应的formatter
      val parseDate: LocalDate = LocalDate.parse(date.trim, formatter)
      val month: Int = parseDate.getMonthValue
      //根据月份判断季度
      dateQuarter = if (month >= 1 && month <= 3) 1
      else if (month >= 4 && month <= 6) 2
      else if (month >= 7 && month <= 9) 3
      else 4
    }
    catch {
      case e: DateTimeParseException => {
        throw new DateTimeParseException(s"返回日期字符串的日期部分: 指定日期不规范,转换失败,date为[$date]", e.getParsedString, e.getErrorIndex)
      }
      case e: Exception => {
        throw new Exception(s"返回日期字符串的日期部分: "+e.getMessage)
      }
    }
    dateQuarter
  }

  /**
    * 返回时间字符串的月份
    *
    * @param date 时间字符串
    * @return int eg: month("1970-11-01 00:00:00") = 11, month("1970-11-01") = 11
    */
  def month(date: String): Int = {
    if (date == null || "".equals(date) || "".equals(date.trim))
      throw new IllegalArgumentException(s"返回时间字符串的月份: 输入的日期字符串不规范,date为[$date]")
    var dateMonth: Int = 0
    try {
      val formatter: DateTimeFormatter = getFormatter(date.trim) //调用getFormatter方法,获得与输入日期字符串相对应的formatter
      val parseDate: LocalDate = LocalDate.parse(date.trim, formatter)
      dateMonth = parseDate.getMonthValue
    }
    catch {
      case e: DateTimeParseException => {
        throw new DateTimeParseException(s"返回日期字符串的日期部分: 指定日期不规范,转换失败,date为[$date]", e.getParsedString, e.getErrorIndex)
      }
      case e: Exception => {
        throw new Exception(s"返回日期字符串的日期部分: "+e.getMessage)
      }
    }
    dateMonth
  }


  /**
    * 根据传入的日期字符串格式,返回对应格式的DateTimeFormatter
    *
    * @param date
    * @return java.time.format.DateTimeFormatter
    */
  def getFormatter(date: String): DateTimeFormatter = {
    var formatter: DateTimeFormatter = null
    //正则判断输入日期字符串的格式
    if (date.matches("^(\\d{4})(\\-)(\\d{2})(\\-)(\\d{2})(\\s+)(\\d{2})(\\:)(\\d{2})(\\:)(\\d{2})$")) {
      formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
    } else if (date.matches("^(\\d{4})(\\-)(\\d{2})(\\-)(\\d{2})(\\s+)(\\d{2})(\\:)(\\d{2})$")) {
      formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")
    } else if (date.matches("^(\\d{4})(\\-)(\\d{2})(\\-)(\\d{2})(\\s+)(\\d{2})$")) {
      formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH")
    } else {
      formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
    }
    formatter
  }


  /**
    * Long类型转换为Double类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def long2Double(input: Long): Double = {

    val res: Double = input.toDouble
    res

  }

  /**
    * Int类型转换为Double类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def int2Double(input: Int): Double = {

    val res: Double = input.toDouble
    res

  }

  /**
    * Int类型转换为Float类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def int2Float(input: Int): Float = {

    val res: Float = input.toFloat
    res

  }

  /**
    * Int类型转换为Long类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def int2Long(input: Int): Long = {

    val res: Long = input.toLong
    res

  }


  /**
    * Long类型转换为Int类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def long2Int(input: Long): Int = {

    val res: Int = input.toInt
    res

  }

  /**
    * Float类型转换为Int类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def float2Int(input: Float): Int = {

    val res: Int = input.toInt
    res

  }

  /**
    * Float类型转换为Long类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def float2Long(input: Float): Long = {
    val res: Long = input.toLong
    res

  }

  /**
    * Float类型转换为Double类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def float2Double(input: Float): Double = {

    val res: Double = input.toDouble
    res

  }

  /**
    * Double类型转换为Long类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def double2Long(input: Double): Long = {

    val res: Long = input.toLong
    res

  }

  /**
    * Double类型转换为Float类型
    *
    * @param input 输入数值
    * @return 返回结果
    */
  def double2Float(input: Double): Float = {
    val res: Float = input.toFloat
    res

  }

  /**
    * String类型转换为String类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def any2Str(input: Any): String = {
    if (input == null) {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        val res: String = input.toString
        res
      } catch {
        case e: Exception =>
          throw new NumberFormatException(s"您输入的参数${input}不是基本数据类型!")
      }
    }
  }

  /**
    * String类型转换为Boolean类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def str2Boolean(input: String): Boolean = {

    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        if (input.equals("0")) {
          true
        } else {
          val res: Boolean = input.toBoolean
          res
        }
      } catch {
        case e: Exception =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")
      }
    }
  }

  /**
    * String类型转换为Char类型
    *
    * @param input 输入字符串（可能丢失数据）
    * @return 返回结果转换后的char数组中第一个元素
    */
  def str2Char(input: String): String = {
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        // 返回字符串的第一个Char类型字符,其他字符丢失
        val res: Char = input.charAt(0)
        res.toString
      } catch {
        case e: Exception =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")

      }
    }
  }

  /**
    * String类型转换为Short类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def str2Short(input: String): Short = {
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        val res: Short = input.toShort
        res
      } catch {
        case e: NumberFormatException =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")
      }
    }
  }

  /**
    * String类型转换为Double类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def str2Double(input: String): Double = {

    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        val res: Double = input.toDouble
        res
      } catch {
        case e: NumberFormatException =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")
      }
    }
  }

  /**
    * String类型转换为Float类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def str2Float(input: String): Float = {
    // 判断参数是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        val res: Float = input.toFloat
        res
      } catch {
        case e: NumberFormatException =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")
      }
    }
  }

  /**
    * String类型转换为Long类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def str2Long(input: String): Long = {
    // 判断输入的字符串是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        val res: Long = input.toLong
        res
      } catch {
        case e: NumberFormatException =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")
      }
    }
  }

  /**
    * String类型转为Int类型
    *
    * @param input 输入字符串
    * @return 返回结果
    */
  def str2Int(input: String): Int = {
    // 判断输入是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的参数为空！")
    } else {
      try {
        // 字符串转化为Int类型数值
        val res: Int = input.toInt
        // 返回结果
        res
      } catch {
        case e: NumberFormatException =>
          throw new NumberFormatException(s"您输入的字符串${input}不是基本数据类型!")
      }
    }
  }

  /**
    * 比较任意类型的两个输入的大小
    *
    * @param input1 输入1
    * @param input2 输入2
    * @return 返回较大值
    */
  def greatest(input1: Any, input2: Any): Any = {
    // 如果参数不合法则抛出异常
    if (input1 == null || input2 == null || input1 == "" || input2 == "") {
      throw new IllegalArgumentException("传入参数错误!")
    }
    // 模式匹配
    input1 match {
      case i: Char =>
        // 模式匹配
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }
      case i: Byte =>
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }

      case i: Short =>
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }
      case i: Int =>
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }
      case i: Long =>
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }

      case i: Float =>
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }

      case i: Double =>
        input2 match {
          case j: Char => if (i > j) i else j
          case j: Byte => if (i > j) i else j
          case j: Short => if (i > j) i else j
          case j: Int => if (i > j) i else j
          case j: Long => if (i > j) i else j
          case j: Float => if (i > j) i else j
          case j: Double => if (i > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i > str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("传入参数错误")
        }
      case i: String =>
        input2 match {
          case j: Char => if (i.charAt(0) > j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case j: String => if (i.compareTo(j) > 0) i else j
          case _ => throw new IllegalArgumentException("传入参数错误")
        }
      case _ => throw new IllegalArgumentException("传入参数错误")
    }
  }


  /**
    * 比较任意类型的两个输入的大小
    *
    * @param input1 输入1
    * @param input2 输入2
    * @return 返回较小值
    */
  def least(input1: Any, input2: Any): Any = {
    // 如果参数不合法则抛出异常
    if (input1 == null || input2 == null || input1 == "" || input2 == "") {
      throw new IllegalArgumentException("您输入的参数为空!")
    }
    // 模式匹配
    input1 match {
      case i: Char =>
        // 模式匹配
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }
      case i: Byte =>
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }

      case i: Short =>
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }
      case i: Int =>
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }
      case i: Long =>
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }

      case i: Float =>
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }

      case i: Double =>
        input2 match {
          case j: Char => if (i < j) i else j
          case j: Byte => if (i < j) i else j
          case j: Short => if (i < j) i else j
          case j: Int => if (i < j) i else j
          case j: Long => if (i < j) i else j
          case j: Float => if (i < j) i else j
          case j: Double => if (i < j) i else j
          // 输入2为String类型时,则拿字符串的首字符和输入1进行比较
          case str: String => if (i < str.charAt(0)) i else str
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }
      case i: String =>
        input2 match {
          case j: Char => if (i.charAt(0) > j) j else i.charAt(0)
          case j: String => if (i.compareTo(j) < 0) i else j
          case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
        }
      case _ => throw new IllegalArgumentException("您输入的参数不是基本数据类型!")
    }
  }

  /**
    * 相反数
    *
    * @param num1 Double类型
    * @return 结果
    */
  def negative(num1: Double): Double = {

    // 返回相反数
    val res: Double = -num1.toDouble
    res
  }

  /**
    * 相反数
    *
    * @param num1 整数类型
    * @return 结果
    */
  def negative(num1: Int): Int = {

    val res: Int = -num1.toInt
    res
  }


  /**
    * num1对num2取模
    *
    * @param num1 double类型
    * @param num2 double类型
    * @return 返回结果值
    */
  def pmod(num1: Double, num2: Double): Double = {

    val res: Double = num1.%(num2)
    res.toDouble

  }

  /**
    * 整数1对整数2取模
    *
    * @param num1 整数1
    * @param num2 整数2
    * @return 返回结果
    */
  def pmod(num1: Int, num2: Int): Int = {

    try {
      val res: Int = num1.%(num2)
      res.toInt
    } catch {
      case e: ArithmeticException =>
        throw new ArithmeticException(s"您输入的参数${num2}为零!")
    }
  }

  /**
    * 绝对值
    *
    * @param num 数
    * @return 返回结果
    */
  def abs(num: Double): Double = {
    Math.abs(num)
  }

  /**
    * 银行家四舍五入保留指定小数位
    *
    * @param num 数
    * @param b   指定小数位
    * @return 返回结果
    */
  def bround(num: Double, b: Int): Double = {

    // 取出num的小数部分
    val fp: String = num.toDouble.toString.split("\\.")(1)
    if (b < 0) {
      throw new IllegalArgumentException(s"您输入的参数b不在正确范围内[0,${fp.length}]！")
    } else if (b > fp.length || b == fp.length) {
      num
    } else if (b == 0) {
      bround(num)
    } else {
      // 扩大10的b次方倍
      val temp: Double = Math.pow(10, b)
      val t: Double = num * temp
      bround(t) / temp
    }
  }

  /**
    * 银行家四舍五入
    *
    * @param num 数
    * @return 四舍五入后的数
    */
  def bround(num: Double): Double = {

    // 取出num1的小数部分
    val fp: String = num.toDouble.toString.split("\\.")(1)
    // 小数部分第一个数字
    val frist: Int = fp.substring(0, 1).toInt
    // 如果第一位数不是5,则按照普通的四舍五入
    if (frist != 5) {
      Math.round(num).toDouble
    } else {
      // 当第一位是5的时候
      // 获取小数部分的长度
      val len: Int = fp.length

      // 长度大于等于2时
      if (len >= 2) {
        // 取出整数部分
        val np: String = num.toDouble.toString.split("\\.")(0)
        // 小数点的上一位,即最后一位整数
        val sed: Double = np.reverse.substring(0, 1).toInt
        if (sed % 2 == 0) {
          // 最后一位整数为偶数
          // 舍去小数部分
          num.toString.split("\\.")(0).toDouble
        } else {
          // 奇数则进位
          Math.round(num).toDouble
        }
      } else {// len==1
        // 如果5后面没有数字,则舍去5并且进位
        Math.round(num).toDouble
      }
    }

  }

  /**
    * 四舍五入
    *
    * @param num
    * @return
    */
  def round(num: Double): Double = {

    Math.round(num).toDouble
  }

  /**
    * 四舍五入（保留指定小数位）
    *
    * @param num 小数
    * @param b   保留小数位
    * @return 结果
    */
  def round(num: Double, b: Int): Double = {

    // 获取小数部分的长度
    val len = num.toDouble.toString.split("\\.")(1).length
    // 指定位数在2~len之间
    if (b < len && b >= 1) {
      val temp: Double = Math.pow(10, b)
      Math.round(num * temp) / temp
    }
    // 指定位数与小数部分长度相等,则直接返回num
    else if (b == len || b > len) {
      num
    } else if (b == 0) {

      Math.round(num).toDouble
    }
    else {
      throw new IllegalArgumentException(s"您输入的参数b不在正确范围[0,${len}]！")
    }
  }


  /**
    * 两数相除
    *
    * @param num1
    * @param num2
    * @return 商
    */
  def div(num1: Double, num2: Double): Double = {

    try {
      val res: Double = num1 / num2
      res
    }
    catch {
      case e: ArithmeticException =>
        throw new ArithmeticException("您输入的除数参数为零!")
    }
  }

  /**
    * 两数相乘
    *
    * @param num1 数1
    * @param num2 数2
    * @return 积
    */
  def mul(num1: Double, num2: Double): Double = {

    val res: Double = num1 * num2
    res
  }

  /**
    * 两数相减
    *
    * @param num1 数1
    * @param num2 数2
    * @return 差
    */
  def sub(num1: Double, num2: Double): Double = {

    val res: Double = num1 - num2
    res
  }

  /**
    * 两数相加
    *
    * @param num1 数1
    * @param num2 数2
    * @return 和
    */
  def add(num1: Double, num2: Double): Double = {

    val res: Double = num1 + num2
    res
  }

  /**
    * UTF-8编码转换成Unicode编码
    *
    * @param input 输入的字符串
    * @return 返回转换后的编码字符串
    */
  def UTF8ToUnicode(input: String): String = {

    // 判断输入字符串是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的字符串为空!")
    }
    else {
      // 先对字符串按照utf-8字符集进行编码
      val dencodestr: Array[Byte] = input.getBytes("UTF-8")
      // 再用指定字符集进行解码
      val encodestr: String = new String(dencodestr, "Unicode")
      encodestr
    }
  }

  /**
    * Unicode字符集转换成UTF-8字符集
    *
    * @param input 输入的字Unicode符串编码
    * @return 输入的UTF-8字符串编码
    */
  def UnicodeToUTF8(input: String): String = {

    // 判断输入字符串是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的字符串为空!")
    }
    else {
      // 先对字符串按照unicode字符集进行编码
      val dencodestr: Array[Byte] = input.getBytes("Unicode")
      // 再用指定字符集进行解码
      val encodestr: String = new String(dencodestr, "UTF-8")
      encodestr
    }
  }

  /**
    * ISO-8859-1字符集转换成GBK字符集
    *
    * @param input 输入字符串
    * @return 返回转换后的字符串
    */
  def ISOToGBK(input: String): String = {

    // 判断输入字符串是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的字符串为空!")
    }
    else {
      // 先对字符串按照ISO-8859-1字符集进行编码
      val dencodestr: Array[Byte] = input.getBytes("ISO-8859-1")
      // 再用指定字符集进行解码
      val encodestr: String = new String(dencodestr, "GBK")
      encodestr
    }

  }


  /**
    * GBK字符集转换成UTF-8字符集
    *
    * @param input 输入字符串
    * @return 返回转换后的字符串
    */
  def GBKToUTF8(input: String): String = {

    // 判断输入字符串是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的字符串为空!")
    }
    else {
      // 先对字符串按照GBK字符集进行编码
      val dencodestr: Array[Byte] = input.getBytes("GBK")
      // 再用指定字符集进行解码
      val encodestr: String = new String(dencodestr, "UTF-8")
      encodestr
    }
  }

  /**
    * UTF-8字符集转换成GBK字符集
    *
    * @param input 输入字符串
    * @return 返回转换后的字符串
    */
  def UTF8ToGBK(input: String): String = {

    // 判断输入字符串是否合法
    if (input == null || input == "") {
      throw new IllegalArgumentException("您输入的字符串为空!")
    }
    else {
      // 先对字符串按照utf-8字符集进行编码
      val dencodestr: Array[Byte] = input.getBytes("UTF-8")
      // 再用指定字符集进行解码
      val encodestr: String = new String(dencodestr, "GBK")
      encodestr
    }
  }

  /**
    * 使用指定的字符集进行重新编码
    *
    * @param input   输入的字符串
    * @param charset 编码字符集
    * @return 返回编码后的字符串
    */
  def recode(input: String, charset: String): String = {
    // 任意参数为空则返回空
    if (input == "" || input == null || charset == "" || charset == null) {
      null
    } else {
      /**
        * 使用指定的字符集对字符串进行重新编码
        *
        * @param input1
        * @param charset1
        * @return
        */
      def NB(input1: String, charset1: String): String = {
        val decondestr: Array[Byte] = input1.getBytes(charset1)
        val encodestr: String = new String(decondestr, charset)
        encodestr
      }
      // 支持的字符集有:GB2312、GBK、GB18030、ISO-8859-1、ASCII、Unicode、UTF-16、UTF-8
      if (charset.equals("GB2312") || charset.equals("GBK") || charset.equals("GB18030") || charset.equals("ISO-8859-1")
          || charset.equals("ASCII") || charset.equals("Unicode") || charset.equals("UTF-16") || charset.equals("UTF-8")) {

        try {
          // 探测当前环境的编码字符集
          val u8: String = new String(input.getBytes(), "UTF-8")
          val gbk: String = new String(input.getBytes(), "GBK")
          val gb2312: String = new String(input.getBytes(), "GB2312")
          val gb18030: String = new String(input.getBytes(), "GB18030")
          val iso: String = new String(input.getBytes(), "ISO-8859-1")
          val ascii: String = new String(input.getBytes(), "ASCII")
          val unicode: String = new String(input.getBytes(), "Unicode")
          val utf16: String = new String(input.getBytes(), "UTF-16")
          // 模式匹配
          input match {
            case `u8` => NB(input, "UTF-8")
            case `gbk` => NB(input, "GBK")
            case `gb2312` => NB(input, "GB2312")
            case `gb18030` => NB(input, "GB18030")
            case `iso` => NB(input, "ISO-8859-1")
            case `ascii` => NB(input, "ASCII")
            case `unicode` => NB(input, "Unicode")
            case `utf16` => NB(input, "UTF-16")
            case _ => throw new UnsupportedOperationException("无法探测您使用的字符集!")
          }
        }
        catch {
          case e: UnsupportedEncodingException =>
            throw new UnsupportedOperationException("不支持您当前环境默认的字符集!")
        }
      } else {
        throw new IllegalArgumentException(s"您输入的字符集${charset}不正确或不支持！")
      }
    }
  }

}
